using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using needle.UI.Controls.Flat.Windows.Forms.Collections;

namespace needle.UI.Controls.Flat.Windows.Docking
{
    [ToolboxItem(false)]
    public class Window : ContainerControl
    {
        protected State mstate;
        protected Zone mparentZone;
        protected WindowDetailCollection mwindowDetails;
        protected Decimal mzoneArea;
        protected Size mminimalSize;
        protected DockingManager mmanager;
        protected bool mautoDispose;
        protected bool mredockAllowed;
        protected bool mfloatingCaption;
        protected bool mcontentCaption;
        protected string mfullTitle;

        public event EventHandler FullTitleChanged; 

		#region Constructors

		public Window(DockingManager manager)
        {
            if (manager == null)
                throw new ArgumentNullException("DockingManager");

            mstate = State.Floating;
            mparentZone = null;
            mzoneArea = 100m;
            mminimalSize = new Size(0,0);
            mmanager = manager;
            mautoDispose = true;
            mfullTitle = "";
            mredockAllowed = true;
            mfloatingCaption = true;
            mcontentCaption = true;

            mwindowDetails = new WindowDetailCollection();

            mwindowDetails.Clearing += new CollectionClearEventHandler(OnDetailsClearing);
            mwindowDetails.Inserted += new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnDetailInserted);
            mwindowDetails.Removing += new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnDetailRemoving);
        }

		#endregion

		#region Properties

        public DockingManager DockingManager
        {
            get { return mmanager; }
        }

        public State State
        {
            get { return mstate; }
			
            set 
            {
                if (mstate != value)
                {
                    mstate = value;

                    foreach(WindowDetail wd in mwindowDetails)
                        wd.ParentStateChanged(mstate);
                }
            }
        }

        public Zone ParentZone
        {
            get { return mparentZone; }
			
            set 
            { 
                if (mparentZone != value)
                {
                    mparentZone = value; 

                    foreach(WindowDetail wd in mwindowDetails)
                        wd.ParentZone = mparentZone;
                }
            }
        }

        public WindowDetailCollection WindowDetails
        {
            get { return mwindowDetails; }
			
            /*set
            {
                mwindowDetails.Clear();
                mwindowDetails = value;
            }*/
        }

        public Decimal ZoneArea
        {
            get { return mzoneArea; }
            set { mzoneArea = value; }
        }

        public Size MinimalSize
        {
            get { return mminimalSize; }
            set { mminimalSize = value; }
        }

        public bool AutoDispose
        {
            get { return mautoDispose; }
            set { mautoDispose = value; }
        }

        public string FullTitle
        {
            get { return mfullTitle; }
        }

        public bool RedockAllowed
        {
            get { return mredockAllowed; }
            set { mredockAllowed = value; }
        }

		#endregion

		#region Virtuals

		public virtual void OnFullTitleChanged(String fullTitle)
		{
			mfullTitle = fullTitle;
            
			if (FullTitleChanged != null)
				FullTitleChanged((object)fullTitle, EventArgs.Empty);
		}

		public virtual Restore RecordRestore(object child) 
		{
			if (mparentZone != null)
			{
				return mparentZone.RecordRestore(this, child, null);
			}

			return null;
		}

		public virtual void PropogateNameValue(PropogateName name, object value)
		{
			if (name == PropogateName.BackColor)
			{
				this.BackColor = (Color)value;
				Invalidate();
			}

			foreach(WindowDetail wd in mwindowDetails)
				wd.PropogateNameValue(name, value);
		}

		protected void OnDetailsClearing(object sender, EventArgs e)
        {
            foreach(WindowDetail wd in mwindowDetails)
            {
                wd.ParentWindow = null;

                wd.ParentZone = null;
            }
        }

        protected void OnDetailInserted(object sender, needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventArgs e)
        {
            WindowDetail wd = sender as WindowDetail;

            wd.ParentWindow = this;

            wd.ParentZone = mparentZone;
        }

        protected void OnDetailRemoving(object sender, needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventArgs e)
        {
            WindowDetail wd = sender as WindowDetail;

            wd.ParentWindow = null;
			
            wd.ParentZone = null;
        }
		
        public virtual void NotifyFullTitleText(string title)
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.NotifyFullTitleText(title);
                
            OnFullTitleChanged(title);
        }

        public virtual void NotifyAutoHideImage(bool autoHidden)
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.NotifyAutoHideImage(autoHidden);
        }

        public virtual void NotifyShowCaptionBar(bool show)
        {
            mcontentCaption = show;
        
            if (mfloatingCaption)
            {
                foreach(WindowDetail wd in mwindowDetails)
                    wd.NotifyShowCaptionBar(show);
            }
        }

        public virtual void NotifyCloseButton(bool show)
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.NotifyCloseButton(show);
        }

        public virtual void NotifyHideButton(bool show)
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.NotifyHideButton(show);
        }

        public virtual void NotifyContentGotFocus()
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.WindowGotFocus();
        }

        public virtual void NotifyContentLostFocus()
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.WindowLostFocus();
        }

        public virtual void WindowDetailGotFocus(WindowDetail wd)
        {
            NotifyContentGotFocus();
        }
		
        public virtual void WindowDetailLostFocus(WindowDetail wd)
        {
            NotifyContentLostFocus();
        }

		#endregion

		#region Methods
        
        public void HideDetails()
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.Hide();
                
            mfloatingCaption = false;
        }

        public void ShowDetails()
        {
            foreach(WindowDetail wd in mwindowDetails)
                wd.Show();

            mfloatingCaption = true;
            
            if (!mcontentCaption)
                NotifyShowCaptionBar(mcontentCaption);
        }

		#endregion
    }
}